package org.example.service;

import lombok.extern.slf4j.Slf4j;
import org.example.entity.CustomerInfo;
import org.example.entity.CustomerOrder;
import org.example.entity.CustomerRepayPlan;
import org.example.mapper.CustomerInfoMapper;
import org.example.mapper.CustomerOrderMapper;
import org.example.mapper.CustomerRepayPlanMapper;
import org.example.service.LoanAllocationService.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;

import static org.example.generator.DataGenerator.*;

/**
 * 贷款数据生成服务
 * 基于 LoanAllocationService 的分配计划生成具体的订单和还款计划数据
 */
@Slf4j
@Service
public class LoanDataGenerationService {

    @Autowired
    private LoanAllocationService loanAllocationService;
    
    @Autowired
    private CustomerInfoMapper customerInfoMapper;
    
    @Autowired
    private CustomerOrderMapper customerOrderMapper;
    
    @Autowired
    private CustomerRepayPlanMapper customerRepayPlanMapper;
    
    // 批量插入配置
    private static final int BATCH_SIZE = 2000;

    // 订单号生成器
    private static final AtomicLong orderNoCounter = new AtomicLong(System.currentTimeMillis());
    private static final AtomicLong customerIdCounter = new AtomicLong(System.currentTimeMillis() * 10000);

    // 产品配置
    private static final String[] PRODUCT_NAMES = {"浩瀚小贷", "盈峰小贷", "新网银行", "江山小贷"};
    private static final int[] LOAN_TERMS = {3, 6, 6,12,12,12,12,12,12,12};
    private static final String[] EDUCATION_LEVELS = {"研究生", "本科", "大专", "高中", "初中"};
    private static final String[] EDUCATIONS = {"研究生", "本科", "大专", "高中", "初中"};
    private static final String[] OCCUPATIONS = {"公司职员", "个体户", "自由职业", "企业主", "其他"};
    private static final String[] MARITAL_STATUS = {"未婚", "已婚", "离异"};
    private static final String[] REPAY_TYPES = {"等额本息", "等额本金"};
    private static final String[] LOAN_PURPOSES = {"消费", "旅游", "教育", "装修", "医疗", "其他"};
    private static final String[] SOURCES = {"闪信", "速贝", "哈啰", "360", "全民", "人品", "拍拍","融360","嘉银","人品钱包",
            "乐享借","金彩贷","快手","小鹅钱包","便荔卡包","钱家","享用钱","百度","云盛花","51信用卡","花财树","转转商城","融安分期","省呗","薪有钱","微博借钱","兑吧"};
    
    // 城市列表
    private static final String[] CITIES = {
        "北京市", "上海市", "天津市", "重庆市",
        "广州市", "深圳市", "成都市", "杭州市", "武汉市", "西安市", "郑州市", "南京市",
        "济南市", "沈阳市", "青岛市", "长沙市", "哈尔滨市", "昆明市", "大连市", "厦门市",
        "石家庄市", "太原市", "南昌市", "长春市", "福州市", "合肥市", "南宁市", "贵阳市",
        "苏州市", "无锡市", "常州市", "宁波市", "温州市", "东莞市", "佛山市", "泉州市"
    };
    private static final Random random = new Random();

    // 还款状态
    private static final String REPAY_STATUS_UNPAID = "0";      // 未还款
    private static final String REPAY_STATUS_NORMAL = "1";      // 正常还款
    private static final String REPAY_STATUS_OVERDUE = "2";     // 逾期还款

    // 订单状态
    private static final String ORDER_STATUS_NORMAL = "正常";
    private static final String ORDER_STATUS_SETTLED = "已结清";

    // 利率配置
    private static final BigDecimal DEFAULT_YEAR_RATE = new BigDecimal("0.12");  // 年利率12%
    private static final BigDecimal DEFAULT_MONTH_RATE = DEFAULT_YEAR_RATE.divide(new BigDecimal("12"), 6, RoundingMode.HALF_UP);

    /**
     * 生成完整的贷款数据（包括客户信息、订单、还款计划）
     */
    public GenerationResult generateLoanData() {
        log.info("========== 开始生成贷款数据 ==========");
        long startTime = System.currentTimeMillis();

        GenerationResult result = new GenerationResult();

        // 1. 生成放款分配计划
        LoanPlan loanPlan = loanAllocationService.generateLoanPlan();
        log.info("放款计划生成完成，总笔数: {}", loanPlan.getTotalLoans());

        // 2. 生成客户信息和订单
        List<CustomerInfo> customerInfoList = new ArrayList<>();
        List<CustomerOrder> orderList = new ArrayList<>();

        for (MonthlyLoanAllocation allocation : loanPlan.getMonthlyAllocations()) {
            generateMonthlyOrders(allocation, customerInfoList, orderList);
        }

        log.info("订单生成完成，客户数: {}, 订单数: {}", customerInfoList.size(), orderList.size());

        // 3. 生成还款计划
        List<CustomerRepayPlan> repayPlanList = new ArrayList<>();
        for (CustomerOrder order : orderList) {
            List<CustomerRepayPlan> plans = generateRepayPlans(order, loanPlan);
            repayPlanList.addAll(plans);
        }

        log.info("还款计划生成完成，计划数: {}", repayPlanList.size());

        // 4. 应用逾期规则
        applyOverdueRules(orderList, repayPlanList, loanPlan);

        // 5. 批量插入数据库
        log.info("开始批量插入数据库...");
        
        // 5.1 批量插入客户信息
        int customerInserted = batchInsertCustomerInfo(customerInfoList);
        log.info("客户信息插入完成，共 {} 条", customerInserted);
        
        // 5.2 批量插入订单
        int orderInserted = batchInsertOrders(orderList);
        log.info("订单插入完成，共 {} 条", orderInserted);
        
        // 5.3 批量插入还款计划
        int repayPlanInserted = batchInsertRepayPlans(repayPlanList);
        log.info("还款计划插入完成，共 {} 条", repayPlanInserted);

        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;

        result.setCustomerInfoList(customerInfoList);
        result.setOrderList(orderList);
        result.setRepayPlanList(repayPlanList);
        result.setDuration(duration);
        result.setCustomerInserted(customerInserted);
        result.setOrderInserted(orderInserted);
        result.setRepayPlanInserted(repayPlanInserted);

        log.info("========== 贷款数据生成完成 ==========");
        log.info("总耗时: {}ms", duration);
        log.info("客户数: {}, 已入库: {}", customerInfoList.size(), customerInserted);
        log.info("订单数: {}, 已入库: {}", orderList.size(), orderInserted);
        log.info("还款计划数: {}, 已入库: {}", repayPlanList.size(), repayPlanInserted);

        return result;
    }
    
    /**
     * 批量插入客户信息
     */
    private int batchInsertCustomerInfo(List<CustomerInfo> customerInfoList) {
        if (customerInfoList == null || customerInfoList.isEmpty()) {
            return 0;
        }

        int totalInserted = 0;
        int totalSize = customerInfoList.size();

        // 分批插入
        for (int i = 0; i < totalSize; i += BATCH_SIZE) {
            int end = Math.min(i + BATCH_SIZE, totalSize);
            List<CustomerInfo> batch = customerInfoList.subList(i, end);

            try {
                int inserted = customerInfoMapper.insertBatch(batch);
                totalInserted += inserted;
                log.debug("批量插入客户信息: {}/{}", end, totalSize);
            } catch (Exception e) {
                log.error("批量插入客户信息失败，批次: {}-{}", i, end, e);
                throw new RuntimeException("批量插入客户信息失败", e);
            }
        }

        return totalInserted;
    }
    
    /**
     * 批量插入订单
     */
    private int batchInsertOrders(List<CustomerOrder> orderList) {
        if (orderList == null || orderList.isEmpty()) {
            return 0;
        }

        int totalInserted = 0;
        int totalSize = orderList.size();

        // 分批插入
        for (int i = 0; i < totalSize; i += BATCH_SIZE) {
            int end = Math.min(i + BATCH_SIZE, totalSize);
            List<CustomerOrder> batch = orderList.subList(i, end);

            try {
                int inserted = customerOrderMapper.insertBatch(batch);
                totalInserted += inserted;
                log.debug("批量插入订单: {}/{}", end, totalSize);
            } catch (Exception e) {
                log.error("批量插入订单失败，批次: {}-{}", i, end, e);
                throw new RuntimeException("批量插入订单失败", e);
            }
        }

        return totalInserted;
    }
    
    /**
     * 批量插入还款计划
     */
    private int batchInsertRepayPlans(List<CustomerRepayPlan> repayPlanList) {
        if (repayPlanList == null || repayPlanList.isEmpty()) {
            return 0;
        }

        int totalInserted = 0;
        int totalSize = repayPlanList.size();

        // 分批插入
        for (int i = 0; i < totalSize; i += BATCH_SIZE) {
            int end = Math.min(i + BATCH_SIZE, totalSize);
            List<CustomerRepayPlan> batch = repayPlanList.subList(i, end);

            try {
                int inserted = customerRepayPlanMapper.insertBatch(batch);
                totalInserted += inserted;
                log.debug("批量插入还款计划: {}/{}", end, totalSize);
            } catch (Exception e) {
                log.error("批量插入还款计划失败，批次: {}-{}", i, end, e);
                throw new RuntimeException("批量插入还款计划失败", e);
            }
        }

        return totalInserted;
    }

    /**
     * 生成每月的订单
     */
    private void generateMonthlyOrders(MonthlyLoanAllocation allocation,
                                       List<CustomerInfo> customerInfoList,
                                       List<CustomerOrder> orderList) {
        YearMonth loanMonth = allocation.getYearMonth();
        int loanCount = allocation.getLoanCount();

        for (int i = 0; i < loanCount; i++) {
            // 生成客户信息
            CustomerInfo customerInfo = generateCustomerInfo(loanMonth);
            customerInfoList.add(customerInfo);

            // 生成订单
            CustomerOrder order = generateOrder(customerInfo, loanMonth);
            orderList.add(order);
        }
    }

    /**
     * 生成客户信息
     */
    private CustomerInfo generateCustomerInfo(YearMonth loanMonth) {
        Random random = new Random();
        int daysInMonth = loanMonth.lengthOfMonth();
        int randomDay = 1 + random.nextInt(daysInMonth);
        LocalDate randomDate = loanMonth.atDay(randomDay);
        String formatter = randomDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        CustomerInfo customer = new CustomerInfo();

        customer.setId(customerIdCounter.incrementAndGet());
        // 使用示例
        Map.Entry<String, String> randomEntry = getRandomCityCode();
        String city = "";
        String code = "";
        if (randomEntry != null) {
            city = randomEntry.getKey();
            code = randomEntry.getValue();
        }
        // 随机选择城市
        customer.setSaleCityName(city);

        // 生成脱敏姓名
        customer.setPlName(generateMaskedName());

        // 生成脱敏手机号
        customer.setPlPhone(generateMaskedPhone());

        // 性别（男75%，女25%）
        customer.setGender(random.nextDouble() < 0.75 ? "男" : "女");

        // 生成脱敏身份证号（根据性别生成倒数第二位）
        customer.setPlIdNo(generateMaskedIdNo(code, customer.getGender()));

        // 年龄（正态分布，没有18以下的）
        customer.setAge(generateNormalDistributedAge());

        // 学历
        customer.setEducation(EDUCATIONS[random.nextInt(EDUCATIONS.length)]);

        // 职业（按分布比例）
        customer.setOccupation(OCCUPATIONS[random.nextInt(OCCUPATIONS.length)]);

        // 婚姻状况
        customer.setMaritalStatus(MARITAL_STATUS[random.nextInt(MARITAL_STATUS.length)]);

        // 渠道来源
        customer.setSource(SOURCES[random.nextInt(SOURCES.length)]);

        // 登录状态
        customer.setLoginStatus("通过");

        // 创建时间（与订单生成时间一致，时分秒在06:00:00到23:00:00之间随机）
        int hour = 6 + random.nextInt(18); // 6-23点
        int minute = random.nextInt(60);   // 0-59分
        int second = random.nextInt(60);   // 0-59秒
        String timeStr = String.format("%02d:%02d:%02d", hour, minute, second);
        customer.setCreatedTime(formatter+ " " + timeStr);

        return customer;
    }

    /**
     * 生成订单
     */
    private CustomerOrder generateOrder(CustomerInfo customerInfo, YearMonth loanMonth) {
        CustomerOrder order = new CustomerOrder();
        // 订单号
        order.setOrderNo("ORD" + customerInfo.getId());
        order.setCustomerId(customerInfo.getId());
        Random random = new Random();

        // 复制客户信息
        order.setPlName(customerInfo.getPlName());
        order.setPlPhone(customerInfo.getPlPhone());
        order.setPlIdNo(customerInfo.getPlIdNo());
        order.setSaleCityName(customerInfo.getSaleCityName());

        // 设置放款时间（月初几天随机）
//        LocalDate loanDate = loanMonth.atDay(1).plusDays(random.nextInt(28));
        order.setFrTime(customerInfo.getCreatedTime().substring(0, 10));

        // 贷款期限
        int term = LOAN_TERMS[random.nextInt(LOAN_TERMS.length)];
        order.setLoanTerm(term + "月");

        // 贷款金额（平均5000左右，精确到百位）
        BigDecimal loanAmount = BigDecimal.valueOf((3000 + random.nextInt(4000)) / 100 * 100)
                .setScale(2, RoundingMode.HALF_UP);
        order.setLoanAmount(loanAmount);

        // 设置产品名称
        order.setProductName(PRODUCT_NAMES[random.nextInt(PRODUCT_NAMES.length)]);

        // 设置利率
        // 对客利率（18%或24%）
        String rate = random.nextBoolean() ? "18%" : "24%";
        order.setProductRate(rate);

        // 初始状态为正常
        order.setStatus(ORDER_STATUS_NORMAL);
        String repayType = REPAY_TYPES[random.nextInt(REPAY_TYPES.length)];

        // 初始剩余应还金额等于放款金额
        order.setRemainPayAmount(order.getLoanAmount());

        // 设置还款方式
        order.setRepayType(repayType);

        // 设置贷款用途
        // 贷款用途（按分布比例）
        order.setLoanUse(LOAN_PURPOSES[random.nextInt(LOAN_PURPOSES.length)]);

        return order;
    }

    /**
     * 生成还款计划
     */
    private List<CustomerRepayPlan> generateRepayPlans(CustomerOrder order, LoanPlan loanPlan) {
        List<CustomerRepayPlan> plans = new ArrayList<>();

        String loanTerm = order.getLoanTerm();
        int term = Integer.parseInt(loanTerm.replace("月", ""));
        BigDecimal loanAmount = order.getLoanAmount();
        String rateStr = order.getProductRate();
        double rate = Double.parseDouble(rateStr.replace("%", "")) / 100.0;
        String repayType = order.getRepayType();

        LocalDate loanDate = LocalDate.parse(order.getFrTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
//        LocalDate now = LocalDate.now();
        LocalDate now = LocalDate.of(2025, 9, 30);

        for (int i = 1; i <= term; i++) {
            CustomerRepayPlan plan = new CustomerRepayPlan();

            plan.setOrderNo(order.getOrderNo());
            plan.setBillId(order.getOrderNo() + "_" + String.format("%03d", i));
            plan.setLoanAmount(loanAmount);
            plan.setLoanTerm(loanTerm);
            plan.setBillTenor((long) i);
            plan.setRate(BigDecimal.valueOf(rate));
            plan.setMonthRate(BigDecimal.valueOf(rate / 12));

            // 应还款日期
            LocalDate dueDate = loanDate.plusMonths(i);
            plan.setDueDate(dueDate);

            // 计算本期应还金额
            calculateRepayAmount(plan, loanAmount, rate, term, repayType, i);

            // 初始状态设置
            plan.setRepayStatus("未到期");
            plan.setActualRepayDate(null);
            plan.setActualRepayMoney(BigDecimal.ZERO);
            plan.setOverdueDays(0);
            plan.setPenaltyInterest(BigDecimal.ZERO);

            plans.add(plan);
        }

        return plans;
    }

    private static void calculateRepayAmount(CustomerRepayPlan plan, BigDecimal loanAmount,
                                             double rate, int term, String repayType, int currentTerm) {
        BigDecimal monthlyRate = BigDecimal.valueOf(rate / 12);

        switch (repayType) {
            case "等额本息":
                // 等额本息计算
                BigDecimal monthlyPayment = loanAmount.multiply(monthlyRate)
                        .multiply(BigDecimal.ONE.add(monthlyRate).pow(term))
                        .divide(BigDecimal.ONE.add(monthlyRate).pow(term).subtract(BigDecimal.ONE), 2, RoundingMode.HALF_UP);

                BigDecimal remainingPrincipal = loanAmount;
                for (int i = 1; i < currentTerm; i++) {
                    BigDecimal interest = remainingPrincipal.multiply(monthlyRate);
                    BigDecimal principal = monthlyPayment.subtract(interest);
                    remainingPrincipal = remainingPrincipal.subtract(principal);
                }

                BigDecimal currentInterest = remainingPrincipal.multiply(monthlyRate);
                BigDecimal currentPrincipal = monthlyPayment.subtract(currentInterest);

                plan.setNowPayPrincipal(currentPrincipal);
                plan.setNowPayInterest(currentInterest);
                plan.setNowPayAmount(monthlyPayment);
                break;

            case "等额本金":
                // 等额本金计算
                BigDecimal monthlyPrincipal = loanAmount.divide(BigDecimal.valueOf(term), 2, RoundingMode.HALF_UP);
                BigDecimal remainingPrincipal2 = loanAmount.subtract(monthlyPrincipal.multiply(BigDecimal.valueOf(currentTerm - 1)));
                BigDecimal currentInterest2 = remainingPrincipal2.multiply(monthlyRate);

                plan.setNowPayPrincipal(monthlyPrincipal);
                plan.setNowPayInterest(currentInterest2);
                plan.setNowPayAmount(monthlyPrincipal.add(currentInterest2));
                break;

//            case "先息后本":
//                // 先息后本计算
//                if (currentTerm == term) {
//                    plan.setNowPayPrincipal(loanAmount);
//                    plan.setNowPayInterest(BigDecimal.ZERO);
//                    plan.setNowPayAmount(loanAmount);
//                } else {
//                    BigDecimal interest = loanAmount.multiply(monthlyRate);
//                    plan.setNowPayPrincipal(BigDecimal.ZERO);
//                    plan.setNowPayInterest(interest);
//                    plan.setNowPayAmount(interest);
//                }
//                break;
        }
    }

    /**
     * 计算等额本息每月还款额
     */
    private BigDecimal calculateMonthlyPayment(BigDecimal loanAmount, BigDecimal monthRate, int termCount) {
        // 等额本息公式：月还款额 = [本金 × 月利率 × (1+月利率)^还款月数] / [(1+月利率)^还款月数 - 1]
        double r = monthRate.doubleValue();
        int n = termCount;

        double numerator = loanAmount.doubleValue() * r * Math.pow(1 + r, n);
        double denominator = Math.pow(1 + r, n) - 1;

        return new BigDecimal(numerator / denominator).setScale(2, RoundingMode.HALF_UP);
    }

    /**
     * 应用逾期规则（优化版）
     * 生成一直逾期的订单，确保数据真实性
     */
    private void applyOverdueRules(List<CustomerOrder> orderList,
                                   List<CustomerRepayPlan> repayPlanList,
                                   LoanPlan loanPlan) {
        log.info("开始应用逾期规则...");

        // 按订单分组还款计划
        Map<String, List<CustomerRepayPlan>> orderPlanMap = new HashMap<>();
        for (CustomerRepayPlan plan : repayPlanList) {
            orderPlanMap.computeIfAbsent(plan.getOrderNo(), k -> new ArrayList<>()).add(plan);
        }

        // 设置截止日期：2025-09-30
        LocalDate cutoffDate = LocalDate.of(2025, 9, 30);
        Random random = new Random();

        // 遍历逾期数据，应用逾期
        for (OverdueData overdueData : loanPlan.getOverdueDataList()) {
            if (!overdueData.isStable()) {
                // 只处理稳定期的逾期数据（第7期后）
                continue;
            }

            YearMonth loanMonth = overdueData.getLoanMonth();
            int overdueCount = overdueData.getOverdueCount();

            // 找到该月的所有订单
            List<CustomerOrder> monthOrders = findOrdersByMonth(orderList, loanMonth);

            if (monthOrders.isEmpty()) {
                continue;
            }

            // 随机选择逾期的订单
            Collections.shuffle(monthOrders);
            int actualOverdueCount = Math.min(overdueCount, monthOrders.size());

            for (int i = 0; i < actualOverdueCount; i++) {
                CustomerOrder order = monthOrders.get(i);
                List<CustomerRepayPlan> plans = orderPlanMap.get(order.getOrderNo());

                if (plans != null && !plans.isEmpty()) {
                    // 按期数排序
                    plans.sort(Comparator.comparing(CustomerRepayPlan::getBillTenor));
                    
                    // 生成一直逾期的订单：从某期开始一直逾期到最后
                    // 随机选择开始逾期的期数（第1-3期开始逾期）
                    int startOverduePeriod = 1 + random.nextInt(Math.min(3, plans.size()));
                    
                    // 从开始逾期期数到最后一期都设置为逾期
                    for (int j = startOverduePeriod - 1; j < plans.size(); j++) {
                        CustomerRepayPlan plan = plans.get(j);
                        
                        // 只处理截止日期之前的还款计划
                        if (plan.getDueDate().isAfter(cutoffDate)) {
                            break;
                        }

                        // 设置逾期状态
                        plan.setRepayStatus(REPAY_STATUS_OVERDUE);

                        // 逾期天数（递增：第一期逾期5-15天，后续期数逐渐增加）
                        int baseOverdueDays = 5 + random.nextInt(11); // 5-15天
                        int additionalDays = (j - startOverduePeriod + 1) * 5; // 每期增加5天
                        int overdueDays = baseOverdueDays + additionalDays;
                        
                        // 限制最大逾期天数不超过90天
                        overdueDays = Math.min(overdueDays, 90);
                        plan.setOverdueDays(overdueDays);

                        // 实际还款日期（逾期后还款）
                        LocalDate actualRepayDate = plan.getDueDate().plusDays(overdueDays);
                        
                        // 确保实际还款日期不超过截止日期
                        if (actualRepayDate.isAfter(cutoffDate)) {
                            actualRepayDate = cutoffDate;
                            // 重新计算逾期天数
                            overdueDays = (int) java.time.temporal.ChronoUnit.DAYS.between(
                                plan.getDueDate(), actualRepayDate);
                            plan.setOverdueDays(overdueDays);
                        }
                        
                        plan.setActualRepayDate(actualRepayDate);

                        // 计算罚息（逾期天数 × 日利率 × 0.5 × 本金）
                        BigDecimal dailyRate = DEFAULT_MONTH_RATE.divide(new BigDecimal("30"), 6, RoundingMode.HALF_UP);
                        BigDecimal penaltyRate = new BigDecimal("0.5");
                        BigDecimal penaltyInterest = plan.getNowPayPrincipal()
                            .multiply(dailyRate)
                            .multiply(new BigDecimal(overdueDays))
                            .multiply(penaltyRate)
                            .setScale(2, RoundingMode.HALF_UP);

                        plan.setPenaltyInterest(penaltyInterest);

                        // 实际还款金额 = 应还本金 + 应还利息 + 罚息
                        BigDecimal actualRepayMoney = plan.getNowPayPrincipal()
                            .add(plan.getNowPayInterest())
                            .add(penaltyInterest);

                        plan.setActualRepayMoney(actualRepayMoney);
                        plan.setActualPrincipal(plan.getNowPayPrincipal());
                        plan.setActualInterest(plan.getNowPayInterest());
                    }
                    
                    // 对于逾期订单，前面的期数设置为正常还款
                    for (int j = 0; j < startOverduePeriod - 1; j++) {
                        CustomerRepayPlan plan = plans.get(j);
                        
                        if (plan.getDueDate().isAfter(cutoffDate)) {
                            break;
                        }
                        
                        plan.setRepayStatus(REPAY_STATUS_NORMAL);
                        plan.setActualRepayDate(plan.getDueDate());
                        plan.setActualPrincipal(plan.getNowPayPrincipal());
                        plan.setActualInterest(plan.getNowPayInterest());
                        plan.setActualRepayMoney(plan.getNowPayAmount());
                        plan.setPenaltyInterest(BigDecimal.ZERO);
                        plan.setOverdueDays(0);
                    }
                }
            }
        }

        // 对于未设置状态的还款计划，根据到期日设置正常还款或未到期
        for (CustomerRepayPlan plan : repayPlanList) {
            if (plan.getRepayStatus().equals(REPAY_STATUS_UNPAID)) {
                // 如果到期日在截止日期之前，设置为正常还款
                if (plan.getDueDate().isBefore(cutoffDate) || plan.getDueDate().isEqual(cutoffDate)) {
                    plan.setRepayStatus(REPAY_STATUS_NORMAL);
                    plan.setActualRepayDate(plan.getDueDate());
                    plan.setActualPrincipal(plan.getNowPayPrincipal());
                    plan.setActualInterest(plan.getNowPayInterest());
                    plan.setActualRepayMoney(plan.getNowPayAmount());
                    plan.setPenaltyInterest(BigDecimal.ZERO);
                    plan.setOverdueDays(0);
                } else {
                    // 到期日在截止日期之后，保持未到期状态
                    plan.setRepayStatus(REPAY_STATUS_UNPAID);
                    plan.setActualRepayDate(null);
                    plan.setActualPrincipal(BigDecimal.ZERO);
                    plan.setActualInterest(BigDecimal.ZERO);
                    plan.setActualRepayMoney(BigDecimal.ZERO);
                    plan.setPenaltyInterest(BigDecimal.ZERO);
                    plan.setOverdueDays(0);
                }
            }
        }

        // 更新订单状态和结清日期
        for (CustomerOrder order : orderList) {
            List<CustomerRepayPlan> plans = orderPlanMap.get(order.getOrderNo());
            if (plans == null || plans.isEmpty()) {
                continue;
            }
            
            // 按期数排序
            plans.sort(Comparator.comparing(CustomerRepayPlan::getBillTenor));

            // 统计还款状态
            long unpaidCount = plans.stream()
                .filter(p -> REPAY_STATUS_UNPAID.equals(p.getRepayStatus()))
                .count();
            
            long paidCount = plans.stream()
                .filter(p -> REPAY_STATUS_NORMAL.equals(p.getRepayStatus()) || 
                           REPAY_STATUS_OVERDUE.equals(p.getRepayStatus()))
                .count();

            if (unpaidCount == 0 && paidCount > 0) {
                // 所有期都已还款，标记为结清
                order.setStatus(ORDER_STATUS_SETTLED);

                // 计算结清日期（最后一期的实际还款日期）
                LocalDate settleDate = plans.stream()
                    .map(CustomerRepayPlan::getActualRepayDate)
                    .filter(Objects::nonNull)
                    .max(LocalDate::compareTo)
                    .orElse(null);
                
                // 确保settleDate不为null
                if (settleDate == null) {
                    // 如果没有实际还款日期，使用最后一期的到期日期
                    settleDate = plans.stream()
                        .map(CustomerRepayPlan::getDueDate)
                        .filter(Objects::nonNull)
                        .max(LocalDate::compareTo)
                        .orElse(null);
                }
                
                order.setSettleDate(settleDate);

                // 剩余应还金额为0
                order.setRemainPayAmount(BigDecimal.ZERO);
            } else {
                // 未结清，保持正常状态
                order.setStatus(ORDER_STATUS_NORMAL);
                order.setSettleDate(null);
                
                // 计算剩余应还金额（未还款的期数）
                BigDecimal remainAmount = plans.stream()
                    .filter(p -> REPAY_STATUS_UNPAID.equals(p.getRepayStatus()))
                    .map(CustomerRepayPlan::getNowPayAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
                order.setRemainPayAmount(remainAmount);
            }
        }

        log.info("逾期规则应用完成");
    }

    /**
     * 查找指定月份的订单
     */
    private List<CustomerOrder> findOrdersByMonth(List<CustomerOrder> orderList, YearMonth yearMonth) {
        List<CustomerOrder> result = new ArrayList<>();

        for (CustomerOrder order : orderList) {
            LocalDate loanDate = LocalDate.parse(order.getFrTime());
            if (YearMonth.from(loanDate).equals(yearMonth)) {
                result.add(order);
            }
        }

        return result;
    }

    /**
     * 生成订单号
     */
    private String generateOrderNo(YearMonth yearMonth) {
        long sequence = orderNoCounter.getAndIncrement();
        return String.format("LN%s%05d", 
            yearMonth.format(DateTimeFormatter.ofPattern("yyyyMM")),
            sequence % 100000);
    }

    /**
     * 生成结果
     */
    public static class GenerationResult {
        private List<CustomerInfo> customerInfoList;
        private List<CustomerOrder> orderList;
        private List<CustomerRepayPlan> repayPlanList;
        private long duration;
        private int customerInserted;
        private int orderInserted;
        private int repayPlanInserted;

        public List<CustomerInfo> getCustomerInfoList() {
            return customerInfoList;
        }

        public void setCustomerInfoList(List<CustomerInfo> customerInfoList) {
            this.customerInfoList = customerInfoList;
        }

        public List<CustomerOrder> getOrderList() {
            return orderList;
        }

        public void setOrderList(List<CustomerOrder> orderList) {
            this.orderList = orderList;
        }

        public List<CustomerRepayPlan> getRepayPlanList() {
            return repayPlanList;
        }

        public void setRepayPlanList(List<CustomerRepayPlan> repayPlanList) {
            this.repayPlanList = repayPlanList;
        }

        public long getDuration() {
            return duration;
        }

        public void setDuration(long duration) {
            this.duration = duration;
        }

        public int getCustomerInserted() {
            return customerInserted;
        }

        public void setCustomerInserted(int customerInserted) {
            this.customerInserted = customerInserted;
        }

        public int getOrderInserted() {
            return orderInserted;
        }

        public void setOrderInserted(int orderInserted) {
            this.orderInserted = orderInserted;
        }

        public int getRepayPlanInserted() {
            return repayPlanInserted;
        }

        public void setRepayPlanInserted(int repayPlanInserted) {
            this.repayPlanInserted = repayPlanInserted;
        }
    }

    /**
     * 随机获取城市代码
     */
    private Map.Entry<String, String> getRandomCityCode() {
        List<Map.Entry<String, String>> entries = new ArrayList<>(CITY_CODE_MAP.entrySet());
        if (entries.isEmpty()) {
            return null;
        }
        int randomIndex = random.nextInt(entries.size());
        return entries.get(randomIndex);
    }
    
    /**
     * 生成正态分布的年龄（18-60岁，平均35岁）
     */
    private int generateNormalDistributedAge() {
        // 使用正态分布生成年龄，平均35岁，标准差10
        double age = 35 + random.nextGaussian() * 10;
        
        // 限制在18-60岁之间
        if (age < 18) {
            age = 18;
        } else if (age > 60) {
            age = 60;
        }
        
        return (int) Math.round(age);
    }

    /**
     * 生成特定数量的测试数据（用于快速测试）
     */
    public GenerationResult generateTestData(int orderCount) {
        log.info("生成测试数据，订单数: {}", orderCount);

        GenerationResult result = new GenerationResult();
        List<CustomerInfo> customerInfoList = new ArrayList<>();
        List<CustomerOrder> orderList = new ArrayList<>();
        List<CustomerRepayPlan> repayPlanList = new ArrayList<>();

        YearMonth currentMonth = YearMonth.now();

        for (int i = 0; i < orderCount; i++) {
            CustomerInfo customerInfo = generateCustomerInfo(currentMonth);
            customerInfoList.add(customerInfo);

            CustomerOrder order = generateOrder(customerInfo, currentMonth);
            orderList.add(order);

            List<CustomerRepayPlan> plans = generateRepayPlans(order, loanAllocationService.generateLoanPlan());
            repayPlanList.addAll(plans);
        }

        result.setCustomerInfoList(customerInfoList);
        result.setOrderList(orderList);
        result.setRepayPlanList(repayPlanList);

        log.info("测试数据生成完成");

        return result;
    }
}

